﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Web.UI.WebControls;

namespace DbTaglio.SvcLayer
{
    public abstract class ValidatorBase<T>
    {
        public class Rule
        {
            public Func<T, bool> TestIfError { get; set; }
            public string Message { get; set; }
        }

     

        protected abstract IEnumerable<Rule> AllRules { get; }

        public IEnumerable<string> Validate(T pDati,ValidationLevel pLevel )
        {
            switch (pLevel)
            {
                case ValidationLevel.NULL:
                    return Enumerable.Empty<string>();
                    break;
                case ValidationLevel.ALL:
                    return this.AllRules.Where(r => r.TestIfError(pDati)).Select(r => r.Message);
                    break;
                case ValidationLevel.ADMIN:
                    break;
                case ValidationLevel.USERS:
                    break;
                default:
                    break;
            }

            return Enumerable.Empty<string>();
           
        }

        
        public bool CanConvertTo<T>(object pInput, bool pAcceptNull = false)
        {
            try
            {
                if (!pAcceptNull)
                    if (pInput == null) return false;

                Type tipo = typeof(T);
                var converter = TypeDescriptor.GetConverter(tipo);
                if (converter != null)
                {
                    if(! converter.CanConvertTo(tipo)) return false;

                    var obj = converter.ConvertTo(pInput, tipo);

                    return true;
                }
                else
                    return false;
            }
            catch (Exception)
            {
                return false;
            }


        }//fM

        public T Convert<T>(object pInput)
        {
            Type tipo = typeof(T);
            var converter = TypeDescriptor.GetConverter(tipo);
            if (converter != null)
            {
                if (converter.CanConvertTo(tipo))   
                    return  (T) converter.ConvertFrom(pInput) ;
            }

            return default(T);

        }//fM
        

        public bool AssertIsNotNullOrEmpty(Object pDato)
        {
            if (pDato == null) return false;
            if (string.IsNullOrEmpty(pDato.ToString().Trim())) return false;

            return true;
        }

        
        public bool ValidateDate(string date)
        {
            if (string.IsNullOrEmpty(date.Trim())) return false;

            DateTime data;
            return DateTime.TryParse(date, out data);
        }

        public DateTime GetDateFromString(string date, bool pIsInItalianFormat)
        {
            DateTime pResult = DateTime.MinValue;
            try
            {
                string[] dateParts = date.Split(new[] { "\\", "-", "/", ":" }, StringSplitOptions.RemoveEmptyEntries);

                if (pIsInItalianFormat)
                {
                    return new DateTime(int.Parse(dateParts[2]), int.Parse(dateParts[1]), int.Parse(dateParts[0]));
                }
                else //english format ? 
                {
                    return new DateTime(int.Parse(dateParts[2]), int.Parse(dateParts[0]), int.Parse(dateParts[1]));
                }

                return pResult;
            }
            catch
            {
                return pResult;
            }
        }


        public T getValFromLister<T>(ListControl pListControl)
        {
            if (pListControl == null) return default(T);
            if (string.IsNullOrEmpty(pListControl.SelectedValue)) return default(T);

            object valore = pListControl.SelectedValue;

            if (AssertIsNotNullOrEmpty(valore))
                if (CanConvertTo<T>(valore))
                    return  Convert<T>(valore);

            return default(T);

        }
        


    }//fC


    public enum ValidationLevel { NULL = 0, ALL, ADMIN, USERS };



}
